package com.zhentao.config;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Arrays;

/**
 * 操作日志切面
 * 
 * @author zhentao
 */
@Aspect
@Component
public class OperationLogAspect {

    private static final Logger logger = LoggerFactory.getLogger(OperationLogAspect.class);

    @Pointcut("@annotation(com.zhentao.config.OperationLog)")
    public void operationLogPointcut() {}

    @Before("operationLogPointcut()")
    public void doBefore(JoinPoint joinPoint) {
        try {
            HttpServletRequest request = getHttpServletRequest();
            if (request != null) {
                MethodSignature signature = (MethodSignature) joinPoint.getSignature();
                Method method = signature.getMethod();
                OperationLog operationLog = method.getAnnotation(OperationLog.class);
                
                String className = joinPoint.getTarget().getClass().getName();
                String methodName = method.getName();
                String operation = operationLog.value();
                String type = operationLog.type();
                String module = operationLog.module();
                
                logger.info("操作日志 - 模块: {}, 类型: {}, 操作: {}, 类: {}, 方法: {}, 请求URL: {}, 请求方法: {}, 参数: {}", 
                    module, type, operation, className, methodName, 
                    request.getRequestURL().toString(), request.getMethod(), 
                    Arrays.toString(joinPoint.getArgs()));
            }
        } catch (Exception e) {
            logger.error("记录操作日志前置通知异常", e);
        }
    }

    @AfterReturning(pointcut = "operationLogPointcut()", returning = "result")
    public void doAfterReturning(JoinPoint joinPoint, Object result) {
        try {
            HttpServletRequest request = getHttpServletRequest();
            if (request != null) {
                MethodSignature signature = (MethodSignature) joinPoint.getSignature();
                Method method = signature.getMethod();
                OperationLog operationLog = method.getAnnotation(OperationLog.class);
                
                String operation = operationLog.value();
                String type = operationLog.type();
                String module = operationLog.module();
                
                logger.info("操作日志 - 模块: {}, 类型: {}, 操作: {}, 执行结果: 成功", 
                    module, type, operation);
            }
        } catch (Exception e) {
            logger.error("记录操作日志后置通知异常", e);
        }
    }

    private HttpServletRequest getHttpServletRequest() {
        try {
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            return attributes != null ? attributes.getRequest() : null;
        } catch (Exception e) {
            return null;
        }
    }
}

